package com.aaa.sbm.util;

import com.aaa.sbm.entity.Menu;
import com.aaa.sbm.entity.Role;
import com.aaa.sbm.entity.User;
import com.aaa.sbm.service.MenuService;
import com.aaa.sbm.service.RoleService;
import com.aaa.sbm.service.UserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.List;

/**
 * @FileName: MyCustomRealm
 * @Description:
 * @Author: zhz
 * @CreateTime: 2024/4/9 14:59
 * @Version: 1.0.0
 */
//@Component  //不用交给spring管理，因为SpringShiroConfig中已经配置Bean 已经交给spring管理
public class MyCustomRealm extends AuthorizingRealm {

    @Resource
    private UserService userService;
    @Resource
    private RoleService roleService;
    @Resource
    private MenuService menuService;

    /**
     * 获取授权信息 （获取角色和权限信息）
     * @param principalCollection
     * @return
     */
    @Override                               //SimplePrincipalCollection->xxxx->PrincipalCollection
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //获取当前登录用户
        User user = (User)principalCollection.getPrimaryPrincipal();
        //获取用户编号
        Integer userId = user.getUserId();
        //实例化返回对象
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        //根据用户编号查询该用户对应的角色列表
        List<Role> roleList = roleService.queryListByUserId(userId);
        //判断
        if(!CollectionUtils.isEmpty(roleList)){
            //循环
            for (Role role : roleList) {
                System.out.println("拥有的角色：-----------------------------"+role.getRoleKey());
                simpleAuthorizationInfo.addRole(role.getRoleKey());
            }
        }
        
        //据用户编号查询该用户对应的权限(菜单)列表
        List<Menu> menuList = menuService.queryListByUserId(userId);
        //判断
        if(!CollectionUtils.isEmpty(menuList)){
            //循环
            for (Menu menu : menuList) {
                //再次判断字符串是否为null
                if(StringUtils.hasLength(menu.getPerms())) {
                    System.out.println("拥有的权限：-----------------------------"+menu.getPerms());
                    simpleAuthorizationInfo.addStringPermission(menu.getPerms());
                }
            }
        }
        return simpleAuthorizationInfo;
    }

    /**
     * 获取认证信息（用户信息）
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
       //获取登录用户名                                   AuthenticationToken
        String userName = authenticationToken.getPrincipal().toString();
        //根据用户名查询对象
        User user = userService.queryByUserName(userName);
        //判断
        if(user==null){
            //为null说明用户名错误（账号错误）
            throw new AccountException();
        }
        //获取加密密码
        String password = user.getPassword();
        //获取盐值
        String salt = user.getSalt();
        //实例化返回对象
        //参数1：就是当前用户( 重要信息，主要信息)
        //参数2： 就是加密密码
        //参数3: 盐值的封装对象ByteSource （为了提高密码破解的复杂度，随机一个字符串做盐值）
        //参数4： 当前realm的名称
        return new SimpleAuthenticationInfo(user,password,
                ByteSource.Util.bytes(salt.getBytes()),getName());
    }
}
